package com.starsoft.quant.strategy.trend;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.starsoft.frame.util.DateUtil;
import com.starsoft.mathlib.macd.MacdReslult;
import com.starsoft.quant.bean.QuantDetail;
import com.starsoft.quant.executor.StrategyReport;
import com.starsoft.quant.strategy.StrategyImpl;
import com.starsoft.smdc.bean.SmdcMarketDaily;
import com.starsoft.smdc.bean.SmdcSecurity;
import com.starsoft.trade.bean.TradeAcountStatus;
import com.starsoft.trade.bean.TradePosition;
import com.starsoft.trade.order.Order;

public class TrendStragegy extends StrategyImpl {
	private static final Logger logger = LoggerFactory.getLogger(TrendStragegy.class);
	
	
	@Override
	public StrategyReport handle() {
		
		List<SmdcSecurity> securityList = context.getSecurityList();
		List<QuantDetail> details = new ArrayList<>();
		for (SmdcSecurity security : securityList) {
			try {
				QuantDetail report = analysis(security);
				details.add(report);
			} catch (Exception e) {
				logger.error(security.getSecId() + " " + DateUtil.toString(context.getCurrentDate())
						+ ",error message:" + e.getMessage(), e);
			}
		}
		StrategyReport report = createReport(details);
		order(report);
		return report;
	}

	private void order(StrategyReport report) {
		Integer acountId = context.getModelContext().getAcountId();
		TradeAcountStatus status = context.getAcountStatus();
		List<TradePosition> positions = status.getPositions();
		
		Double leftCash = status.getSummary().getCash();
		Double netAsset = status.getSummary().getNetAssert();
		// sell
		for (TradePosition position : positions) {
			String secId = position.getId().getSecId();
			QuantDetail detail = report.getDetail(secId);
			if (detail == null) {
				continue;
			}
			if (detail.getRating()<=0) {
				double num = position.getSecNumAfs();
				double closePrice = context.getMarket(secId).getClosePrice();
				Order order = new Order(secId, -num, closePrice);
				leftCash += context.getOrderService().getOrderMoney(acountId, order);
				report.addOrder(order);
			}
		}
		// buy
		if (leftCash / netAsset > 0.05) {
			for (QuantDetail detail : report.getDetails()) {
				if (detail.getRating()>=2) {
					String secId = detail.getId().getSecId();
					double closePrice = context.getMarket(secId).getClosePrice();
					double num = (int) (leftCash/closePrice);
					Order order = new Order(secId, num, closePrice);
					leftCash += context.getOrderService().getOrderMoney(acountId, order);
					report.addOrder(order);
					break;
				}
			}
		}
	}
	
	private QuantDetail analysis(SmdcSecurity security) {
		Date currentDate = context.getCurrentDate();
		SmdcMarketDaily latestMarket = context.getMarket(security.getSecId());
		MacdReslult macd = context.getIndicatorService().getMacd(security, 3, currentDate, latestMarket);
		
		double[] macdHist = macd.getMacdHist();
		int outSinal = 0;
		outSinal +=macdHist[0]<0?-1:1;
		outSinal +=macdHist[1]<0?-1:1;
		outSinal +=macdHist[2]<0?-1:1;

		double[] macdDiff = macd.getMacd();
		outSinal +=macdDiff[0]<0?-1:1;
		outSinal +=macdDiff[1]<0?-1:1;
		outSinal +=macdDiff[2]<0?-1:1;

		Double rating = Double.valueOf(outSinal);
		QuantDetail detail = createDetail(security, rating);
		detail.setCol1(String.valueOf(macdHist[2]));
		detail.setCol2(String.valueOf(macd.getMacd()[2]));
		detail.setCol3(String.valueOf(macd.getMacdSignal()[2]));
		return detail;
	}
	
}
